package drds.plus.sql_process.abstract_syntax_tree.expression.item.function;

import drds.plus.common.jdbc.Parameters;
import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import drds.plus.sql_process.optimizer.OptimizerException;

import java.util.ArrayList;
import java.util.List;

public class OrsFilterImpl extends FunctionImpl<OrsFilter> implements OrsFilter {


    public OrsFilterImpl() {
        argList = new ArrayList<Filter>();
    }

    public String getFunctionName() {
        return Operation.group_or.getOperationString();
    }

    public void setOperation(Operation operation) {
        if (operation != Operation.group_or) {
            throw new UnsupportedOperationException();
        }
    }

    public Object getColumn() {
        List<Filter> filterList = getFilterList();
        if (filterList != null && filterList.size() > 1) {
            return ((BooleanFilter) filterList.get(0)).getColumn();
        }

        return null;
    }

    public void setColumn(Object column) {
        // ignore

    }

    public Operation getOperation() {
        return Operation.group_or;
    }

    public List<Filter> getFilterList() {
        return argList;
    }

    public void setFilterList(List<Filter> filterList) {
        this.setArgList(filterList);
    }

    public void addFilter(Filter filter) {
        if (!(filter instanceof BooleanFilter)) {
            throw new OptimizerException("OrsFilterImpl only support BooleanFilterImpl");
        }
        this.argList.add(filter);

    }

    public OrsFilter assignment(Parameters parameters) {
        OrsFilter orsFilter = super.assignment(parameters);
        orsFilter.setOperation(this.getOperation());
        return orsFilter;
    }


    public OrsFilter copy() {
        OrsFilter orsFilter = ObjectCreateFactory.createOrsFilter();
        super.copy(orsFilter);
        orsFilter.setOperation(this.getOperation());
        return orsFilter;
    }

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((argList == null) ? 0 : argList.hashCode());
        return result;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof OrsFilter)) {
            return false;
        }
        OrsFilter other = (OrsFilter) obj;
        if (getOperation() != other.getOperation()) {
            return false;

        }
        if (getFilterList() == null) {
            return other.getFilterList() == null;
        } else
            return getFilterList().equals(other.getFilterList());
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        executePlanVisitor.visit(this);
    }

}
